import { NMTopoBaseCommand } from '@app-cad/environments/nextmesh/types/command';

import { useEffect, useRef, useState } from 'react';
import i18n from '@app-cad/common/utils/i18next';
import { CommandDialog } from '@amcax/base';
import { CommandLabeledItemWrapper } from '@app-cad/common/components/command-form/item-wrapper';
import { Select } from 'antd';
import CmdInteractor from './CmdInteractor';
import {
  MultiPickInput,
  PickInputValueType,
} from '@app-base/common/components/pick-input/3d';
import { useCommand } from '@app-base/common/hooks/useCommand';
import { CommandFormFooter } from '@app-base/common/components/command-form/footer';
import { NonDialogPickableCommandForm } from '@app-base/common/components/command-form/pickable';
import { ComCommand } from './component';
import {
  args,
  format,
  InitType,
  OptionType,
  setSchema,
  tip,
  uiSchema,
} from './type';
import { documentV2 } from '@app-nextmesh/domain';

export function Command({ onClose, title }) {
  const [param, setParam] = useState<InitType>({
    mode: 'shortest',
    ...args,
  });
  useCommand('cmd-mesh-trim', {
    onClose,
  });
  const cmdRef = useRef<CmdInteractor>(null);
  const [active, setActive] = useState<number>(1);
  useEffect(() => {
    cmdRef.current = new CmdInteractor({ setParam, setActive });
    cmdRef.current.addExit(onClose);
    return () => {
      cmdRef.current?.destroy();
      cmdRef.current = null;
    };
  }, []);
  const [picked, setPicked] = useState<any>();
  const [execute, setExecute] = useState<boolean>(false);
  // form
  const isExecute = () => {
    if (param.mode === 'planar') {
      return;
    }
    if (param.relyOn1?.entityId && param.relyOn2?.entityId) {
      setExecute(true);
    } else {
      setExecute(false);
    }
  };
  // execute
  useEffect(() => {
    isExecute();
  }, [param]);
  // select change
  const onChange = (val) => {
    if (val !== param.mode) {
      setParam({ ...args, mode: val });
      setActive(0);
      cmdRef.current.selfReset();
      setPicked(null);
      if (val === 'vertical') {
        cmdRef.current.setMode(['face']);
        cmdRef.current.isPick = true;
        setActive(1);
      } else {
        cmdRef.current.setMode(['line', 'point']);
        cmdRef.current.picker.clickNull();
      }
    }
  };
  // pick change
  const onPick = (result) => {
    setPicked(result[0]);
    cmdRef.current.setLimitPick(result[0]);
    setParam({ ...args, mode: 'shortest' });
    setActive(1);
  };
  // focus
  const onFocus = () => {
    setActive(0);
  };
  async function checkAndFinishDraw() {
    const isParam = format(param, picked);
    await documentV2.trim(isParam);
  }
  const remove = (it) => {
    if (param.mode === 'vertical' && 'relyOn' + it === 'relyOn1') {
      setParam({ ...args, mode: 'vertical' });
      cmdRef.current.picker.clickNull();
      cmdRef.current.removeByFormKey(['relyOn1', 'relyOn2']);
    } else {
      setParam((state) => ({
        ...state,
        ['relyOn' + it]: {
          name: '',
          entityId: '',
          point: null,
        },
      }));
      cmdRef.current.removeByFormKey('relyOn' + it);
    }
  };
  const isFormDataValid = () => {
    if (param.relyOn && param.target?.length > 0) {
      return true;
    }
    return false;
  };
  return (
    <CommandDialog
      title={title}
      onClose={onClose}
      placement='topLeft'>
      <CommandLabeledItemWrapper
        textClassName='text-reset'
        className='mt-5 px-5'
        label='类型'>
        <Select
          options={OptionType}
          value={param.mode}
          onChange={onChange}
        />
      </CommandLabeledItemWrapper>
      {/* 线 */}
      {param.mode === 'shortest' && (
        <CommandLabeledItemWrapper
          textClassName='text-reset'
          className='mt-5 px-5'
          label=''>
          <MultiPickInput
            autoFocus
            active={active === 0}
            value={[picked]}
            allowPickType={[PickInputValueType.Surface]}
            onPick={onPick}
            onFocus={onFocus}
            placeholder='请输入面'
          />
        </CommandLabeledItemWrapper>
      )}
      {param.mode !== 'planar' ? (
        <>
          {[1, 2].map((it) => (
            <ComCommand
              label={tip[param.mode]?.['relyOn' + it]}
              isActive={active === it}
              onFocus={() => setActive(it)}
              cmdRef={cmdRef.current}
              param={param}
              options={[it === 1 ? 'face' : 'line']}
              relyKey={it === 1 ? 'relyOn1' : 'relyOn2'}
              onRemove={() => remove(it)}
            />
          ))}
          <div className='w-full mt-2'>
            <CommandFormFooter
              onClose={onClose}
              onSubmit={checkAndFinishDraw}
              isSubmitDisabled={!execute}
            />
          </div>
        </>
      ) : (
        <NonDialogPickableCommandForm
          onCancel={onClose}
          schema={setSchema}
          formData={param}
          extraUiSchema={uiSchema}
          submitText={'确定'}
          onChange={(v) => setParam((state) => ({ ...state, ...v }))}
          onSubmit={checkAndFinishDraw}
          isFormDataValid={isFormDataValid()}
        />
      )}
    </CommandDialog>
  );
}

export const cmdTopoTrim: NMTopoBaseCommand = {
  id: 'cmdTrim',
  label: 'command.topo.trim',
  icon: 'commands/feature/trim',
  create: function (label: string, onClose: () => void) {
    return (
      <Command
        title={i18n.t(label)}
        onClose={onClose}
      />
    );
  },
};
